package com.sky.utils;

import com.sky.properties.MinioProperties;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * 人脸识别工具类
 */
@Component
public class FaceRecognitionUtil {
    // 新增Minio相关依赖
    private final MinioClient minioClient;
    private final String bucketName;

    @Autowired
    public FaceRecognitionUtil(MinioClient minioClient, MinioProperties minioProperties) {
        this.minioClient = minioClient;
        this.bucketName = minioProperties.getBucketName();
        checkBucketExists();
    }

    private void checkBucketExists() {
        try {
            boolean exists = minioClient.bucketExists(
                    BucketExistsArgs.builder().bucket(bucketName).build()
            );
            if (!exists) {
                minioClient.makeBucket(
                        MakeBucketArgs.builder().bucket(bucketName).build()
                );
                System.out.println("Bucket does not exist, creating: " + bucketName);
            }
        } catch (Exception e) {
            System.out.println("Error checking/creating bucket: " + e.getMessage());
        }
    }


    public static class StreamWorker implements Runnable {
        // 任务ID
        private final String taskId;
        // RTSP流地址
        private final String rtspUrl;
        // Minio客户端
        private final MinioClient minioClient;
        // 存储桶名称
        private final String bucketName;
        // 是否正在运行
        private volatile boolean running = true;
        // FFmpeg帧抓取器
        private FFmpegFrameGrabber grabber;
        // Java2D帧转换器
        private Java2DFrameConverter converter;

        // 构造函数，用于初始化StreamWorker对象

        public StreamWorker(String taskId, String rtspUrl,
                            MinioClient minioClient, String bucketName) {
            // 初始化taskId
            this.taskId = taskId;
            // 初始化rtspUrl
            this.rtspUrl = rtspUrl;
            // 初始化minioClient
            this.minioClient = minioClient;
            // 初始化bucketName
            this.bucketName = bucketName;
        }

        @Override
        public void run() {
            try {
                // 设置Ffmpeg日志回调
                // FFmpegLogCallback.setLevel(FFmpegLogCallback.DEBUG);  // 设为DEBUG级别
                FFmpegLogCallback.set();

                // 初始化Ffmpeg帧抓取器
                grabber = new FFmpegFrameGrabber(rtspUrl);
                // 设置RTSP传输协议为TCP
                // 设置仅处理视频流,忽略音频流
                grabber.setOption("allowed_media_types", "video");
                grabber.setOption("rtsp_transport", "tcp");
                // 设置帧率为25
                grabber.setFrameRate(25);
                // 设置图像宽度为640
                grabber.setImageWidth(640);
                // 设置图像高度为480
                grabber.setImageHeight(480);

                // 初始化Java2D帧转换器
                converter = new Java2DFrameConverter();
                // 启动帧抓取器
                grabber.start();
                System.out.println("Started 数据流抓取" + rtspUrl);

                Frame frame;
                // 循环抓取帧
                while (running && (frame = grabber.grabImage()) != null) {
                    // 处理帧
                    if (frame.image != null) {
                        processFrame(frame);
                    }
                }
            } catch (Exception e) {
                System.err.println("Error processing RTSP stream: " + e.getMessage());
            } finally {
                // 停止帧抓取器
                stop();
            }
        }

        // 处理帧
        private void processFrame(Frame frame) {
            try {
                // 将帧转换为BufferedImage
                BufferedImage image = converter.getBufferedImage(frame);
                // 如果图像为空，则返回
                if (image == null) return;

                // 如果帧号是帧率的倍数，则上传帧到Minio
                if (grabber.getFrameNumber() % grabber.getFrameRate() == 0) {
                    // 构造对象名称
                    String objectName = String.format("%s/%d.jpg",
                            taskId,
                            System.currentTimeMillis()
                    );

                    // 将图像写入字节数组输出流
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ImageIO.write(image, "jpg", os);
                    byte[] imageData = os.toByteArray();

                    // 上传帧到Minio
                    minioClient.putObject(
                            PutObjectArgs.builder()
                                    .bucket(bucketName)
                                    .object(objectName)
                                    .stream(new ByteArrayInputStream(imageData), imageData.length, -1)
                                    .contentType("image/jpeg")
                                    .build()
                    );

                    System.out.println("Uploaded frame: " + objectName);
                }
            } catch (Exception e) {
                System.err.println("抓取流程失败" + e.getMessage());

            }
        }

        // 停止帧抓取器
        public void stop() {
            running = false;
            try {
                if (grabber != null) {
                    grabber.stop();
                    grabber.close();
                }
                if (converter != null) {
                    converter.close();
                }
                System.out.println("Stopped 数据流抓取" + rtspUrl);
            } catch (Exception e) {
                System.out.println("停止失败" + e.getMessage());
            }
        }
    }


}
